package com.lbt.weixin.server.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import weixin.popular.api.MessageAPI;
import weixin.popular.bean.message.templatemessage.TemplateMessage;
import weixin.popular.bean.message.templatemessage.TemplateMessageItem;
import weixin.popular.bean.message.templatemessage.TemplateMessageResult;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lbt.framework.exception.MyException;
import com.lbt.framework.jackson.result.StatusResult;
import com.lbt.weixin.common.bean.entity.User;
import com.lbt.weixin.server.common.CommonConfig;
import com.lbt.weixin.server.common.CommonUtil;
import com.lbt.weixin.server.common.WeixinUtil;

/**
 * 事件消息
 * @author Moyq5
 * @date 2016年9月19日
 */
@Controller
@RequestMapping("/receive")
public class ReceiveController extends BaseController {
	
	private static Logger log = LoggerFactory.getLogger(ReceiveController.class);
	
	@Resource
	ObjectMapper objectMapper;
	
	@RequestMapping(method = RequestMethod.POST)
	@ResponseBody
	public StatusResult receive(@RequestBody String data, String mobile, String action, long timestamp, String nonce, String sign) {
		StatusResult result = new StatusResult();
		
		checkSign(mobile, action, data, timestamp, nonce, sign);
		
		User user = new User();
		user.setMobile(mobile);
		List<User> userList = userService.list(user);
		if (userList.size() != 1) {
			throw new MyException("用户不存在");
		}
		user = userList.get(0);
		
		TemplateMessage tm = null;
		if (action.equals("consume")) {
			tm = consumeMessage(user.getOpenId(), data);
		} else if (action.equals("maintain")) {
			tm = maintainMessage(user.getOpenId(), data);
		} else if (action.equals("inspect")) {
			tm = inspectMessage(user.getOpenId(), data);
		} else if (action.equals("insurance")) {
			tm = insuranceMessage(user.getOpenId(), data);
		}
		
		String accessToken = WeixinUtil.getAccessToken();
		TemplateMessageResult apiResult = MessageAPI.messageTemplateSend(accessToken, tm);

		if (!apiResult.isSuccess()) {
			throw new MyException("[" + apiResult.getErrcode() + "]"
					+ apiResult.getErrmsg());
		}
		
		result.setOk();
		return result;
	}
	
	/**
	 * 消息提醒消息
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	private TemplateMessage consumeMessage(String openId, String data) {
		ConsumeData noticeData = null;
		String detailUrl = null;
		try {
			noticeData = objectMapper.readValue(data, ConsumeData.class);
			detailUrl = CommonConfig.getInstance().getThisDomain() + "/v2/satisfy.html?soNbr=" + noticeData.getOrderNo();
		} catch (Exception e) {
			log.error("json解析失败：", e);
			throw new MyException(e.getMessage());
		}
		
		if (null == noticeData.getFirst()) {
			noticeData.setFirst("尊敬的客户，您的消费信息如下，如有疑问请致电13696942595。\n");
		}
		if (null == noticeData.getRemark()) {
			noticeData.setRemark("\n点击本消息进行评价，可获赠积分。");
		}
		
		Map<String, TemplateMessageItem> params = new HashMap<String, TemplateMessageItem>();
		params.put("first", new TemplateMessageItem(noticeData.getFirst() + "\n", "#000000"));
		params.put("keyword1", new TemplateMessageItem(noticeData.getOrderNo(), "#000000"));
		params.put("keyword2", new TemplateMessageItem(noticeData.getDateTime(), "#000000"));
		params.put("keyword3", new TemplateMessageItem(noticeData.getCarNo(), "#000000"));
		params.put("keyword4", new TemplateMessageItem(noticeData.getMileage(), "#000000"));
		params.put("keyword5", new TemplateMessageItem(noticeData.getFee(), "#173177"));
		params.put("remark", new TemplateMessageItem("\n" + noticeData.getRemark(), "#000000"));
		
		TemplateMessage tm = new TemplateMessage();
		tm.setTemplate_id("pZhzAuDazLVBMpLqx9KzrjWKWOr2BfAsUgMxB9svtOo");
		tm.setTouser(openId);
		tm.setUrl(detailUrl);
		tm.setData(new LinkedHashMap<String, TemplateMessageItem>(params));

		return tm;
	}
	
	/**
	 * 养护提醒消息
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	private TemplateMessage maintainMessage(String openId, String data) {
		MaintainData maintainData = null;
		String detailUrl = null;
		try {
			maintainData = objectMapper.readValue(data, MaintainData.class);
			detailUrl = CommonConfig.getInstance().getThisDomain() + "/v2/maintain.html?carNo=" + maintainData.getCarNo();
		} catch (Exception e) {
			log.error("json解析失败：", e);
			throw new MyException(e.getMessage());
		}
		
		Map<String, TemplateMessageItem> params = new HashMap<String, TemplateMessageItem>();
		params.put("first", new TemplateMessageItem(maintainData.getFirst() + "\n", "#000000"));
		params.put("keyword1", new TemplateMessageItem(maintainData.getCarNo(), "#000000"));
		params.put("keyword2", new TemplateMessageItem(maintainData.getDueDate(), "#000000"));
		params.put("remark", new TemplateMessageItem("\n" + maintainData.getRemark(), "#000000"));
		
		TemplateMessage tm = new TemplateMessage();
		tm.setTemplate_id("-HITT1gHV2rkyX924q7jNpyrhrN81SX0Qk6Cmp1Vu2M");
		tm.setTouser(openId);
		tm.setUrl(detailUrl);
		tm.setData(new LinkedHashMap<String, TemplateMessageItem>(params));

		return tm;
	}
	
	/**
	 * 年检提醒消息
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	private TemplateMessage inspectMessage(String openId, String data) {
		InspectData inspectData = null;
		String detailUrl = null;
		try {
			inspectData = objectMapper.readValue(data, InspectData.class);
			detailUrl = CommonConfig.getInstance().getThisDomain() + "/v2/maintain.html?carNo=" + inspectData.getCarNo();
		} catch (Exception e) {
			log.error("json解析失败：", e);
			throw new MyException(e.getMessage());
		}
		
		if (null == inspectData.getFirst()) {
			inspectData.setFirst("尊敬的车主您好，您的车辆年检即将到期\n");
		}
		if (null == inspectData.getRemark()) {
			inspectData.setRemark("\n点击查看详情\n");
		}
		
		Map<String, TemplateMessageItem> params = new HashMap<String, TemplateMessageItem>();
		params.put("first", new TemplateMessageItem(inspectData.getFirst(), "#000000"));
		params.put("keyword1", new TemplateMessageItem(inspectData.getCarNo(), "#000000"));
		params.put("keyword2", new TemplateMessageItem(inspectData.getInspectDate(), "#000000"));
		params.put("remark", new TemplateMessageItem(inspectData.getRemark(), "#000000"));
		
		TemplateMessage tm = new TemplateMessage();
		tm.setTemplate_id("DIVDMyqrGFQI7SSXv2cP8IbCRmmEZbG1FGYcI4jd_d4");
		tm.setTouser(openId);
		tm.setUrl(detailUrl);
		tm.setData(new LinkedHashMap<String, TemplateMessageItem>(params));

		return tm;
	}
	
	/**
	 * 保险到期提醒消息
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	private TemplateMessage insuranceMessage(String openId, String data) {
		InsuranceData insuranceData = null;
		String detailUrl = null;
		try {
			insuranceData = objectMapper.readValue(data, InsuranceData.class);
			detailUrl = CommonConfig.getInstance().getThisDomain() + "/v2/maintain.html?carNo=" + insuranceData.getCarNo();
		} catch (Exception e) {
			log.error("json解析失败：", e);
			throw new MyException(e.getMessage());
		}
		
		if (null == insuranceData.getFirst()) {
			insuranceData.setFirst("尊敬的车主您好，您的车辆保险即将到期\n");
		}
		if (null == insuranceData.getRemark()) {
			insuranceData.setRemark("\n点击查看详情\n");
		}
		
		Map<String, TemplateMessageItem> params = new HashMap<String, TemplateMessageItem>();
		params.put("first", new TemplateMessageItem(insuranceData.getFirst(), "#000000"));
		params.put("keynote1", new TemplateMessageItem(insuranceData.getInsureDate(), "#000000"));
		params.put("keynote2", new TemplateMessageItem(insuranceData.getExpireDate(), "#000000"));
		params.put("remark", new TemplateMessageItem(insuranceData.getRemark(), "#000000"));
		
		TemplateMessage tm = new TemplateMessage();
		tm.setTemplate_id("f5iT8ibStEjdI-2bLeOEpTmdgoPQFUSXqFuQZqJg6pA");
		tm.setTouser(openId);
		tm.setUrl(detailUrl);
		tm.setData(new LinkedHashMap<String, TemplateMessageItem>(params));

		return tm;
	}

	private void checkSign(String mobile, String action, String data, long timestamp, String nonce, String sign) {
		if (System.currentTimeMillis() - timestamp > 60000) {// 1分钟内有效
			throw new MyException("请求已失效");
		}
		System.out.println(Charset.defaultCharset());
		String partyCode = CommonConfig.getInstance().getLbtPartyCode();
		String key = CommonConfig.getInstance().getLbtKey();
		
		try {
			data = URLEncoder.encode(data, "utf-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		System.out.println(mobile + action + data + timestamp + partyCode + key + nonce);
		String resultSign = CommonUtil.md5Encode(mobile + action + data + timestamp + partyCode + key + nonce);
		if (!sign.equals(resultSign)) {
			throw new MyException("签名未通过");
		}
	}
	
	public static class ConsumeData extends Data {
		private String orderNo;
		private String fee;
		private String dateTime;
		private String mileage;
		public String getOrderNo() {
			return orderNo;
		}
		public void setOrderNo(String orderNo) {
			this.orderNo = orderNo;
		}
		public String getFee() {
			return fee;
		}
		public void setFee(String fee) {
			this.fee = fee;
		}
		public String getDateTime() {
			return dateTime;
		}
		public void setDateTime(String dateTime) {
			this.dateTime = dateTime;
		}
		public String getMileage() {
			return mileage;
		}
		public void setMileage(String mileage) {
			this.mileage = mileage;
		}
	}
	
	/**
	 * 车辆保养提醒内容
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	public static class MaintainData extends Data {
		private String dueDate;// 到期日期
		public String getDueDate() {
			return dueDate;
		}
		public void setDueDate(String dueDate) {
			this.dueDate = dueDate;
		}
	}
	
	/**
	 * 车辆年检提醒内容
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	public static class InspectData extends Data {
		private String inspectDate;// 年检日期
		public String getInspectDate() {
			return inspectDate;
		}
		public void setInspectDate(String inspectDate) {
			this.inspectDate = inspectDate;
		}
	}
	
	/**
	 * 车辆保险到期提醒内容
	 * @author Moyq5
	 * @date 2017年2月19日
	 */
	public static class InsuranceData extends Data {
		private String insureDate;// 上次投保日期
		private String expireDate;// 到期日期
		public String getInsureDate() {
			return insureDate;
		}
		public void setInsureDate(String insureDate) {
			this.insureDate = insureDate;
		}
		public String getExpireDate() {
			return expireDate;
		}
		public void setExpireDate(String expireDate) {
			this.expireDate = expireDate;
		}
	}
	
	private static class Data {
		private String mobile;
		private String carNo;
		private String first;
		private String remark;
		public String getMobile() {
			return mobile;
		}
		public void setMobile(String mobile) {
			this.mobile = mobile;
		}
		public String getCarNo() {
			return carNo;
		}
		public void setCarNo(String carNo) {
			this.carNo = carNo;
		}
		public String getFirst() {
			return first;
		}
		public void setFirst(String first) {
			this.first = first;
		}
		public String getRemark() {
			return remark;
		}
		public void setRemark(String remark) {
			this.remark = remark;
		}
		
	}

}
